// 水印配置选项接口
interface WatermarkOptions {
  /** 水印容器，默认为 document.body */
  container?: HTMLElement
  /** canvas 元素宽度，默认 240 */
  width?: string | number
  /** canvas 元素高度，默认 100 */
  height?: string | number
  /** 文字对齐方式，默认 'center' */
  textAlign?: CanvasTextAlign
  /** 文字基准线，默认 'middle' */
  textBaseline?: CanvasTextBaseline
  /** 字体大小及样式，默认 '16px Microsoft Yahei' */
  font?: string
  /** 水印颜色，默认 '#000' */
  fillStyle?: string
  /** 水印内容，默认 '验证水印' */
  content?: string
  /** 透明度，默认 0.3 */
  globalAlpha?: number
  /** 文字旋转角度，默认 16 */
  rotate?: number
  /** 元素堆叠顺序，默认 1000 */
  zIndex?: number
  /** 是否可以取消，默认 true */
  isCancel?: boolean
  /** 水印间距X，默认 240 */
  gapX?: number
  /** 水印间距Y，默认 100 */
  gapY?: number
  /** 是否观察DOM变化，默认 true */
  observe?: boolean
  /** 字符间距，默认 'normal' */
  letterSpacing?: string
}

// 水印实例管理器
class WatermarkManager {
  private static instances = new Map<HTMLElement, { element: HTMLElement; observer?: MutationObserver }>()

  static add(container: HTMLElement, watermarkElement: HTMLElement, observer?: MutationObserver) {
    this.instances.set(container, { element: watermarkElement, observer })
  }

  static remove(container: HTMLElement) {
    const instance = this.instances.get(container)
    if (instance) {
      instance.element.remove()
      if (instance.observer) {
        instance.observer.disconnect()
      }
      this.instances.delete(container)
    }
  }

  static clear() {
    this.instances.forEach((instance, container) => {
      this.remove(container)
    })
  }
}

function watermark(options: WatermarkOptions = {}) {
  const {
    container = document.body, // 容器
    width = 240, // canvas元素宽
    height = 100, // canvas元素高
    textAlign = 'center', // 文字对齐
    textBaseline = 'middle', // 基准线
    font = '16px Microsoft Yahei', // 字体大小及样式
    fillStyle = '#000', // 自定义水印的颜色
    content = '验证水印', // 水印内容
    globalAlpha = 0.3, // 设置图形和图像透明度的值
    rotate = 16, // 文字旋转角度
    zIndex = 1000, // 元素堆叠顺序
    isCancel = true,
    gapX = 240, // 水印间距X
    gapY = 100, // 水印间距Y
    observe = true, // 是否观察DOM变化
    letterSpacing = 'normal', // 字符间距
  } = options

  // 先移除之前的水印
  WatermarkManager.remove(container)

  const canvas = document.createElement('canvas')
  const canvasWidth = typeof width === 'number' ? width.toString() : width
  const canvasHeight = typeof height === 'number' ? height.toString() : height
  canvas.setAttribute('width', canvasWidth)
  canvas.setAttribute('height', canvasHeight)
  const ctx = canvas.getContext('2d') // 获取 canvas2d 上下文

  if (!ctx) return

  ctx.globalAlpha = globalAlpha
  ctx.textAlign = textAlign
  ctx.textBaseline = textBaseline
  ctx.font = font
  ctx.fillStyle = fillStyle

  // 设置字符间距 (注意：letterSpacing 可能不被所有浏览器支持)
  if (letterSpacing !== 'normal' && 'letterSpacing' in ctx) {
    ;(ctx as any).letterSpacing = letterSpacing
  }

  // 计算canvas中心点
  const canvasWidthNum = typeof width === 'number' ? width : parseInt(width)
  const canvasHeightNum = typeof height === 'number' ? height : parseInt(height)
  const centerX = canvasWidthNum / 2
  const centerY = canvasHeightNum / 2

  // 移动到中心点，然后旋转
  ctx.translate(centerX, centerY)
  ctx.rotate((Math.PI * rotate) / 180)

  // 在中心点绘制文字
  ctx.fillText(content, 0, 0)

  const base64Url = canvas.toDataURL() // 返回一个包含图片展示的 data URI

  const watermarkDiv = document.createElement('div')

  // 判断是否为全局水印（容器为body）
  const isGlobal = container === document.body

  const styleStr = isGlobal
    ? `
      position:fixed !important;
      top:0px !important;
      left:0px !important;
      width:100% !important;
      height:100% !important;
      z-index:${zIndex} !important;
      pointer-events:none !important;
      background-repeat:repeat !important;
      background-image:url('${base64Url}') !important;
      background-size:${gapX}px ${gapY}px !important;`
    : `
      position:absolute !important;
      top:0px !important;
      left:0px !important;
      width:100% !important;
      height:100% !important;
      z-index:${zIndex} !important;
      pointer-events:none !important;
      background-repeat:repeat !important;
      background-image:url('${base64Url}') !important;
      background-size:${gapX}px ${gapY}px !important;`

  watermarkDiv.setAttribute('style', styleStr)
  watermarkDiv.classList.add('__wm') // 为元素添加"__wm"类名
  watermarkDiv.setAttribute('data-watermark', 'true') // 添加标识符

  // 设置容器的相对定位（局部水印需要）
  if (!isGlobal) {
    const containerStyle = window.getComputedStyle(container)
    if (containerStyle.position === 'static') {
      container.style.position = 'relative'
    }
  }

  // 添加到指定容器
  container.appendChild(watermarkDiv)

  // 监听删除 防止用户去手动删除，如果手动删除，重新添加
  let observer: MutationObserver | undefined
  if (observe && isCancel) {
    const MutationObserver = window.MutationObserver || (window as any).WebKitMutationObserver
    // 检查浏览器是否支持这个API
    if (MutationObserver) {
      observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
          if (mutation.type === 'childList') {
            const removedNodes = Array.from(mutation.removedNodes)
            const hasWatermarkRemoved = removedNodes.some((node) => node instanceof HTMLElement && node.classList.contains('__wm'))
            if (hasWatermarkRemoved) {
              // 延迟重新添加，避免无限循环
              setTimeout(() => watermark(options), 100)
            }
          } else if (mutation.type === 'attributes' && mutation.target instanceof HTMLElement) {
            const target = mutation.target
            if (target.classList.contains('__wm') && target.getAttribute('style') !== styleStr) {
              target.setAttribute('style', styleStr)
            }
          }
        })
      })

      observer.observe(container, {
        attributes: true, // 观察目标节点的属性节点
        subtree: true, // 观察目标节点的所有后代节点
        childList: true, // 观察目标节点的子节点
      })
    }
  }

  // 将实例添加到管理器
  WatermarkManager.add(container, watermarkDiv, observer)

  // 返回销毁函数
  return () => {
    WatermarkManager.remove(container)
  }
}

// 导出类型和函数
export type { WatermarkOptions }
export { WatermarkManager }
export default watermark
